package pl.edu.mimuw.irs.core.model.design.net;

import pl.edu.mimuw.irs.core.global.IDManager;
import pl.edu.mimuw.irs.core.model.design.net.refinement.Refinement;
import pl.edu.mimuw.irs.core.model.petrinet.IPlace;
import pl.edu.mimuw.irs.core.model.petrinet.Place;
import pl.edu.mimuw.irs.core.util.Position;

/**
 * @author Jakub Rauch 
 * Created on: 2009-05-07
 */
public class IRSPlace extends IRSAbstractNode<IPlace> implements IPlace {

	private static final long serialVersionUID = 4744674617764045683L;
	
	// *** Attributes

	@Override
	public int getTokens() {
		return getPetriNode().getTokens();
	}

	@Override
	public void setTokens(int tokens) {
		getPetriNode().setTokens(tokens);
	}
	
	// *** Constructors

	public IRSPlace(IDManager idManager, String id,
			Refinement refinement, Position position, int tokens) {
		super(new Place(idManager, id, position, tokens));
		refine(refinement);
	}

	public IRSPlace(IDManager idManager, String id, Position position, int tokens) {
		this(idManager, id, Refinement.NONE, position, tokens);
	}

	public IRSPlace(IDManager idManager, String id, Position position) {
		this(idManager, id, position, 0);
	}

	public IRSPlace(IDManager idManager, Position position) {
		this(idManager, null, position);
	}

	public IRSPlace(IDManager idManager, String id) {
		this(idManager, id, new Position());
	}

	public IRSPlace(IDManager idManager) {
		this(idManager, (String) null);
	}
	
	/**
	 * Copying constructor.
	 * @param node
	 */
	public IRSPlace(IRSPlace place) {
		super((IRSAbstractNode<IPlace>)place);
	}

	// *** Methods

	public boolean isInPlace() {
		return getIncomingArcs().size() == 0;
	}

	public boolean isOutPlace() {
		return getOutgoingArcs().size() == 0;
	}

	@Override
	public void addTokens(int num) {
		getPetriNode().addTokens(num);
	}

	@Override
	public void removeTokens(int num) {
		getPetriNode().removeTokens(num);
	}

	// Fragmentation private methods

//	public List<IRSNode> getAtomicNodes() {
//		List<IRSNode> leafs = new LinkedList<IRSNode>();
//		if (getRefinement().equals(Refinement.NONE)) {
//			leafs.add(this);
//		} else {
//			for (IRSNode node : getChildren()) {
//				IRSNode rcpNode = (IRSNode) node;
//				leafs.addAll(rcpNode.getAtomicNodes());
//			}
//		}
//		return leafs;
//	}
//
//	public List<IRSNode> getExpandedNodes() {
//		List<IRSNode> leafs = new LinkedList<IRSNode>();
//		if (!isExpanded()) {
//			leafs.add(this);
//			return leafs;
//		} else {
//			for (IRSNode node : getChildren()) {
//				IRSNode rcpNode = (IRSNode) node;
//				leafs.addAll(rcpNode.getExpandedNodes());
//			}
//		}
//		return leafs;
//	}
//
//	public void detach() {
//		super.detach();
//		for (IRSNode child : getChildren()) {
//			child.detach();
//		}
//	}
//
//	@Override
//	public void detach() {
//		if (isDetached()) 
//			throw new InternalException(Cause.PETRI_NET_REPEATED_NODE_DETACH, this);
//		setDetached(true);
//	}
//	
//	@Override
//	public void detach() {
//		if (getNet() != null) getNet().removeNode(this);
//		for (Arc incomingArc : getIncomingArcs()) {
//			incomingArc.getTransition().removeArc(incomingArc);
//		}
//		
//		for (Arc outgoingArc : getOutgoingArcs()) {
//			outgoingArc.getTransition().removeArc(outgoingArc);
//		}
//		super.detach();
//	}
	
	@Override
	public IRSPlace clone() {
		return new IRSPlace(this);
	}
}
